package com.alibaba.dubbo.common.instance;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 单例管理器
 * @author kingbo.ruan
 * 2014.9.18
 *
 */
public class SingletonLoader {
	
	static class InstanceLoaderHolder{
		static SingletonLoader INSTANCE = new SingletonLoader();
	}
	
	private SingletonLoader(){}
	static public SingletonLoader getInstance(){
		return InstanceLoaderHolder.INSTANCE;
	}
	
	
	ConcurrentHashMap<Class<?>, Object> INSTANCES = new ConcurrentHashMap<Class<?>, Object>();
	
	@SuppressWarnings("unchecked")
	public <T> T getInstance(String clazzName){
		try {
			return (T) getInstance(Class.forName(clazzName));
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		return null;
	}
	
	
	@SuppressWarnings("unchecked")
	public <T> T getInstance(Class<T> clazz){
		T t = (T) INSTANCES.get(clazz);
		if(t != null){
			return t;
		}
		
		try {
			Method m = clazz.getDeclaredMethod("getInstance", new Class<?>[]{});
			if(m != null && (m.getModifiers() & Modifier.STATIC) != 0){
				t = (T) m.invoke(null, new Object[]{});
			}
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		}
		if(t != null){
			INSTANCES.put(clazz, t);
		}
		
		return t;
	}
}
